package com.ruyuan.user.server.domain.converter;

import com.ruyuan.common.model.BusinessException;
import com.ruyuan.common.model.ErrorCode;
import com.ruyuan.common.model.Features;
import com.ruyuan.user.api.model.enums.GenderEnum;
import com.ruyuan.user.api.model.enums.RecruitTypeEnum;
import com.ruyuan.user.api.model.enums.UserJobRelationTypeEnum;
import com.ruyuan.user.server.domain.model.Job;
import com.ruyuan.user.server.domain.model.User;
import com.ruyuan.user.server.domain.service.JobDomainService;
import com.ruyuan.user.server.repository.bean.UserDO;
import com.ruyuan.user.server.repository.bean.UserExample;
import com.ruyuan.user.server.repository.bean.UserJobRelationDO;
import com.ruyuan.user.server.repository.mapper.UserMapper;
import com.ruyuan.user.server.util.PasswordUtil;
import com.ruyuan.user.server.util.PinyinUtil;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xx
 */
@Component
public class UserConverter {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JobDomainService jobDomainService;

    private static final String INIT_PASSWORD = "1234";

    public User convertDOToModel(UserDO userDO) {
        User user = new User();
        //同学自己可以更换成get set方法
        BeanUtils.copyProperties(userDO, user);
        if (!userDO.getFeatures().isEmpty()) {
            user.setFeatures(Features.of(userDO.getFeatures()));
        }
        user.setGender(GenderEnum.getByCode(userDO.getGender()));
        user.setRecruitType(RecruitTypeEnum.getByCode(userDO.getRecruitType()));
        if (!user.getFeatures().isEmpty() && StringUtils.hasLength(user.getFeatures().getFeature("code"))) {
            user.setCode(user.getFeatures().getFeature("code"));
        }
        Map<UserJobRelationTypeEnum, List<Job>> userJobMap = jobDomainService.queryUserJobs(userDO.getId());
        List<Job> mainJobs = userJobMap.get(UserJobRelationTypeEnum.MAIN_JOB);
        if (!CollectionUtils.isEmpty(mainJobs)) {
            user.setMainJob(mainJobs.get(0));
        }
        if (MapUtils.isNotEmpty(userJobMap)) {
            Map<UserJobRelationTypeEnum, List<Job>> otherJobs = new HashMap<>(userJobMap);
            otherJobs.remove(UserJobRelationTypeEnum.MAIN_JOB);
            user.setOtherJobs(otherJobs);
        }
        return user;
    }

    public UserDO convertModelToDO(User user) {
        UserDO userDO = new UserDO();
        userDO.setId(user.getId());
        userDO.setModifier(user.getModifier());
        userDO.setGmtModified(new Date());
        userDO.setRootOrgId(1L);
        userDO.setName(user.getName());
        userDO.setPhoto(user.getPhoto());
        userDO.setBirthday(user.getBirthday());
        userDO.setEntryDate(user.getEntryDate());
        userDO.setBecomeTrailDate(user.getBecomeTrailDate());
        userDO.setBecomeRegularDate(user.getBecomeRegularDate());
        userDO.setStatus(1);
        userDO.setNation(user.getNation());
        userDO.setIdentityCardNum(user.getIdentityCardNum());
        userDO.setEmail(user.getEmail());
        userDO.setPhone(user.getPhone());
        userDO.setAddress(user.getAddress());
        userDO.setSalary(user.getSalary());
        userDO.setLevel(user.getLevel());
        userDO.setIsDeleted(user.getIsDeleted());
        if (user.getGender() != null) {
            userDO.setGender(user.getGender().getCode());
        }
        if (user.getRecruitType() != null) {
            userDO.setRecruitType(user.getRecruitType().getCode());
        }
        if (StringUtils.hasLength(user.getCode())) {
            user.getFeatures().addFeature("code", user.getCode());
        }
        if (!user.getFeatures().isEmpty()) {
            userDO.setFeatures(user.getFeatures().toString());
        }
        if (user.getId() == null) {
            //插入 初始化用户名 密码 creator gmtCreate
            userDO.setCreator(user.getModifier());
            userDO.setGmtCreate(new Date());
            userDO.setIsDeleted("n");
            //张三 -> zhangsan 李四 -> lisi 张散 -> zhangsan2
            try {
                String username = PinyinUtil.toHanyuPinyin(user.getName());
                //防止同名
                userDO.setUserName(preventDuplicate(username));
            } catch (BadHanyuPinyinOutputFormatCombination e) {
                throw new BusinessException(ErrorCode.code("USER_NAME_FORMAT_INVALID"));
            }
            userDO.setPassword(PasswordUtil.generatePassword(userDO.getUserName(), INIT_PASSWORD));
        }
        return userDO;
    }

    private String preventDuplicate(String username) {
        long existCount = 1;
        String checkName = username;
        int i = 1;
        while (existCount > 0) {
            UserExample userExample = new UserExample();
            userExample.createCriteria().andUserNameEqualTo(checkName);
            existCount = userMapper.countByExample(userExample);
            if (existCount == 0) {
                break;
            }
            i++;
            checkName = username + i;
        }
        return checkName;
    }

    public UserJobRelationDO convertMainUserJobRelation(User user) {
        if (user.getMainJob() != null) {
            UserJobRelationDO userJobRelationDO = new UserJobRelationDO();
            userJobRelationDO.setJobId(user.getMainJob().getId());
            userJobRelationDO.setUserId(user.getId());
            userJobRelationDO.setRelationType(UserJobRelationTypeEnum.MAIN_JOB.getCode());
            userJobRelationDO.setCreator(user.getModifier());
            userJobRelationDO.setModifier(user.getModifier());
            userJobRelationDO.setIsDeleted("n");
            userJobRelationDO.setGmtModified(new Date());
            userJobRelationDO.setGmtCreate(new Date());
            return userJobRelationDO;
        }
        return null;
    }

}
